/**
 * Created by Bin_Shi on 2016/11/17.
 * 玩家角色相关脚本
 */
var player_radius = 50;

//初始化一个属于自己的角色
function initPlayer(id, name){
    var birth = getBirthPlace();
    return {
        id:id,
        color:getRandomColor(),
        x:birth.x,
        y:birth.y,
        alive:1,
        name:name,
        radius:player_radius,
        t_x:birth.x,
        t_y:birth.y,
        v:0
    };
}

//创建一个非己方角色
function createPlayer(data){
    return {
        id:data.id,
        color:data.color,
        x:data.x,
        y:data.y,
        alive:data.alive,
        name:data.name,
        radius:player_radius,
        time:100,
        t_x:data.t_x,
        t_y:data.t_y,
        v:data.v
    }
}

//绘制角色
function drawPlayer(canvas, chess, flag){
    if(chess.alive == 1){
        var position = '';
        if(flag){
            position = getPlayerCanvasPosition(canvas, chess.x, chess.y);
        }
        else{
            position = getOthersCanvasPosition(canvas, chess);
        }
        var ctx=canvas.getContext("2d");
        if(chess.name == '滑稽'){
            var img=new Image();
            img.src="./face/huaji.png";
            ctx.drawImage(img,position.x - 50,position.y - 50);
        }
        else if(chess.name == '喷水'){
            var img=new Image();
            img.src="./face/penshui.png";
            ctx.drawImage(img,position.x - 50,position.y - 50);
        }
        else{
            ctx.beginPath();
            ctx.arc(position.x, position.y, chess.radius,0,360,false);
            ctx.fillStyle = chess.color;
            ctx.fill();
            ctx.closePath();
            ctx.font = "16px 宋体";
            ctx.fillStyle = "black";
            var font_width = ctx.measureText(chess.name).width;
            ctx.fillText(chess.name, position.x - Math.floor(font_width/2), position.y + 4);
        }
    }
}

//获取颜色
function getRandomColor(){
    var colors = [
        '#7476f1',
        '#2ee7be',
        '#aa71d0',
        '#ff906e',
        '#de2163',
        '#f69d35',
        '#e0d730',
        '#1c437a',
        '#7840a3',
        '#e2548e',
        '#ff5064',
        '#ef283f',
        '#07449f',
        '#ffc341',
        '#f8d4a0',
        '#01b06d',
        '#9fdd7c',
        '#fd4d36',
        '#fde59d',
        '#fe4157',
        '#01a6ac'
    ];
    var index = Math.floor(Math.random()*colors.length);
    return colors[index];
}

function getPlayerCanvasPosition(canvas, x, y){
    var width = Math.floor(canvas.width / 2);
    var height = Math.floor(canvas.height / 2);
    var position = {
        x:0,
        y:0
    };
    if(map.width - x < width){
        position.x = canvas.width - (map.width - x);
    }
    else if(x < width){
        position.x = x;
    }
    else{
        position.x = width;
    }
    if(map.height - y < height){
        position.y = canvas.height - (map.height - y);
    }
    else if(y < height){
        position.y = y;
    }
    else{
        position.y = height;
    }
    return position;
}

function getOthersCanvasPosition(canvas, other){
    var sight = getSight(player, canvas);
    return {
        x:other.x - sight.x0,
        y:other.y - sight.y0
    };
}

function drawOthers(canvas, other_player){
    for(var x in other_player){
        if(other_player[x].time <= 0){
            other_player.splice(x, 1);
        }
        else{
            var other = other_player[x];
            //判断是否要绘制
            var sight = getSight(player, canvas);
            //1.在视野范围内
            if(other.x >= sight.x0 && other.x <= sight.x1 && other.y >= sight.y0 && other.y <= sight.y1){
                drawPlayer(canvas, other, false);
            }
            //2.在视野上方，部分进入视野内
            else if(other.x >= sight.x0 && other.x <= sight.x1 && sight.y0 - other.y <= other.radius){
                drawPlayer(canvas, other, false);
            }
            //3.在视野左方，部分进入视野内
            else if(other.y >= sight.y0 && other.y <= sight.y1 && sight.x0 - other.x <= other.radius){
                drawPlayer(canvas, other, false);
            }
            //4.在视野下方，部分进入视野内
            else if(other.y >= sight.y0 && other.y <= sight.y1 && other.y - sight.y1 <= other.radius){
                drawPlayer(canvas, other, false);
            }
            //5.在视野右方，部分进入视野内
            else if(other.y >= sight.y0 && other.y <= sight.y1 && other.x - sight.x1 <= other.radius){
                drawPlayer(canvas, other, false);
            }
            //6.在视野左上方，部分进入视野内
            else if(getDistance(sight.x0, sight.y0, other.x, other.y) < other.radius){
                drawPlayer(canvas, other, false);
            }
            //7.在视野左下方，部分进入视野内
            else if(getDistance(sight.x0, sight.y1, other.x, other.y) < other.radius){
                drawPlayer(canvas, other, false);
            }
            //8.在视野右上方，部分进入视野内
            else if(getDistance(sight.x1, sight.y0, other.x, other.y) < other.radius){
                drawPlayer(canvas, other, false);
            }
            //9.在视野右下方，部分进入视野内
            else if(getDistance(sight.x1, sight.y1, other.x, other.y) < other.radius){
                drawPlayer(canvas, other, false);
            }
            other_player[x].time--;
        }
    }
}

//玩家移动方法
function move(){
    if(!player.alive){
        return player;
    }
    if(player.v != 0 || player.x != player.t_x || player.y != player.t_y){
        var w = player.x - player.t_x;
        var h = player.y - player.t_y;
        var l = Math.sqrt(w*w + h*h);
        var v_x = 0;
        var v_y = 0;
        if(l != 0){
            v_x = player.v * w / l;
            v_y = player.v * h / l;
        }
        if(player.x != player.t_x){
            //往左走
            if(v_x > 0){
                if(w <= v_x) {
                    player.x = player.t_x;
                }
                else{
                    player.x = Math.round(player.x - v_x);
                }
            }
            //往右走
            else if(v_x < 0){
                if(w >= v_x){
                    player.x = player.t_x;
                }
                else{
                    player.x = Math.round(player.x - v_x);
                }
            }
        }
        if(player.y != player.t_y){
            //往上走
            if(v_y > 0){
                if(h <= v_y){
                    player.y = player.t_y;
                }
                else{
                    player.y = Math.round(player.y - v_y);
                }
            }
            //往下走
            else if(v_y <0){
                if(h >= v_y){
                    player.y = player.t_y;
                }
                else{
                    player.y = Math.round(player.y - v_y);
                }
            }
        }
        return player;
    }
}

//检测碰撞
function checkCollision(){
    var collision_players = [];
    var i = 0;
    for(var x in others){
        if(!others[x].alive){
            others.splice(x, 1);
            continue;
        }
        var collision_range = others[x].radius + player.radius + 2 * force_radius;
        var l = getDistance(others[x].x, others[x].y, player.x, player.y);
        if(l < collision_range){
            collision_players[i] = others[x];
            i++;
        }
    }
    return collision_players;
}

//受到碰撞时的运动方式
//TODO:运动太鬼畜
function collisionMove(collision, v){
    if(!player.alive){
        return;
    }
    //分解当前用户的速度
    var player_w = player.t_x - player.x;
    var player_h = player.t_y - player.y;
    var player_v_x = 0;
    var player_v_y = 0;
    if(player_w != 0 && player_h != 0){
        player_v_x = v * player_w / Math.sqrt(Math.pow(player_w, 2) + Math.pow(player_h, 2));
        player_v_y = v * player_h / Math.sqrt(Math.pow(player_w, 2) + Math.pow(player_h, 2));
    }
    var collision_v = [];
    for(var x in collision){
        //计算给的速度
        var distance = getDistance(player.x, player.y, collision[x].x, collision[x].y);
        var c_v = Math.round(min_force_v + (100 - Math.round(distance)) * force_v);
        //分解别的玩家给的速度
        var collision_w = collision[x].x - player.x;
        var collision_h = collision[x].y - player.y;
        var collision_v_x = c_v * collision_w / distance;
        var collision_v_y = c_v * collision_h / distance;
        collision_v[x] = {
            v_x:collision_v_x,
            v_y:collision_v_y
        }
    }
    var v_x = player_v_x;
    var v_y = player_v_y;
    for(var y in collision_v){
        v_x += collision_v[y].v_x;
        v_y += collision_v[y].v_y;
    }
    player.x = Math.round(player.x + v_x);
    player.y = Math.round(player.y + v_y);
}

function getDistance(x0, y0, x1, y1){
    return Math.sqrt(Math.pow((x0 - x1), 2) + Math.pow((y0 - y1), 2));
}

//检查是否碰到了障碍物
function checkObstacles(ob){
    //检测是否碰到了定义的障碍物
    for(var x in ob){
        //先判断圆和方的位置关系
        var ob_x0 = ob[x].x0;
        var ob_y0 = ob[x].y0;
        var ob_x1 = ob[x].x0 + ob[x].width;
        var ob_y1 = ob[x].y0 + ob[x].width;
        var p_x = player.x;
        var p_y = player.y;
        //上方
        if(p_y <= ob_y0){
            //圆心的x值在正方形内
            if(p_x >= ob_x0 && p_x <= ob_x1 && Math.abs(p_y - ob_y0) < player.radius){
                return true;
            }
            //圆心在正方形外，判断左上角和右上角
            //左上角
            if(p_x < ob_x0 && getDistance(p_x, p_y, ob_x0, ob_y0) < player.radius){
                return true;
            }
            //右上角
            if(p_x > ob_x1 && getDistance(p_x, p_y, ob_x1, ob_y0) < player.radius){
                return true;
            }
            continue;
        }
        //下方
        if(p_y > ob_y1){
            //圆心的x值在正方形内
            if(p_x >= ob_x0 && p_x <= ob_x1 && Math.abs(p_y - ob_y1) < player.radius){
                return true;
            }
            //圆心在正方形外，判断左下角和右下角
            //左下角
            if(p_x < ob_x0 && getDistance(p_x, p_y, ob_x0, ob_y1) < player.radius){
                return true;
            }
            //右下角
            if(p_x > ob_x1 && getDistance(p_x, p_y, ob_x1, ob_y1) < player.radius){
                return true;
            }
            continue;
        }
        //左方
        if(p_x <= ob_x0){
            //圆心的y值在正方形内
            if(p_y >= ob_y0 && p_y <= ob_y1 && Math.abs(p_x - ob_x0) < player.radius){
                return true;
            }
            //圆心在正方形外，判断左上角和左下角
            //左上角
            if(p_y < ob_y0 && getDistance(p_x, p_y, ob_x0, ob_y0) < player.radius){
                return true;
            }
            //左下角
            if(p_y > ob_y1 && getDistance(p_x, p_y, ob_x0, ob_y1) < player.radius){
                return true;
            }
            continue;
        }
        //右方
        if(p_x > ob_x1){
            //圆心的y值在正方形内
            if(p_y >= ob_y0 && p_y <= ob_y1 && Math.abs(p_x - ob_x1) < player.radius){
                return true;
            }
            //圆心在正方形外，判断右上角和右下角
            //右上角
            if(p_y < ob_y0 && getDistance(p_x, p_y, ob_x0, ob_y1) < player.radius){
                return true;
            }
            //右下角
            if(p_y > ob_y1 && getDistance(p_x, p_y, ob_x1, ob_y1) < player.radius){
                return true;
            }
            continue;
        }
        //内部
        if(p_x <= ob_x1 && p_x >= ob_x0 && p_y <= ob_y0 && p_y >= ob_y1){
            return true;
        }
    }
    //检测是否碰到了边缘
    var sight = getSight(player, canvas);
    //左
    if(sight.x0 == 0){
        if(player.x < player.radius + border_width){
            return true;
        }
    }
    //右
    if(sight.x1 == map.width){
        if(player.x > map.width - border_width - player.radius){
            return true;
        }
    }
    //上
    if(sight.y0 == 0){
        if(player.y < player.radius + border_width){
            return true;
        }
    }
    //下
    if(sight.y1 == map.height){
        if(player.y > map.height - border_width - player.radius){
            return true;
        }
    }
    return false;
}

//死亡事件
function death(){
    player.alive = 0;
    $('#overlay').show();
    $('#welcome').hide();
    $('#replay').show();
    wsSend(ws, player);
}

//获取出生点
function getBirthPlace(){
    var birth_place = {
        x:0,
        y:Math.floor(Math.random()*1800 + 100)
    };
    //1.不在障碍物中出生
    var cannot = [];
    for(var x in obstacles){
        var not_radius = obstacles[x].width + player_radius;
        var not_range = [obstacles[x].x0 - not_radius, obstacles[x].x0 + not_radius];
        cannot[x] = not_range;
    }
    var count = cannot.length;
    //2.不在玩家所在的点内出生
    for(var y in others){
        var not_range = [others[y].x - others[y].radius, others[y].x + others[y].radius];
        cannot[y + count] = not_range;
    }
    //合并不能出生的区间
    cannot = merge(cannot);
    //将不能出生的区间变成可以出生的区间
    var can_array = [(border_width + 1) + player_radius];
    var i = 1;
    for(var z in cannot){
        can_array[i] = cannot[z][0];
        i++;
        can_array[i] = cannot[z][1];
        i++;
    }
    can_array[i] = map.width - (border_width + 1) - player_radius;
    var can_range = [];
    var p = 0;
    for(var j = 0; j < can_array.length; j = j + 2){
        can_range[p] = [can_array[j], can_array[j + 1]];
        p++;
    }
    //从可以出生的区间中随便选出一个
    var index = Math.floor(Math.random() * can_range.length);
    //在选出的区间中选一个点
    birth_place.x = Math.floor(can_range[index][0] + Math.random() * (can_range[index][1] - can_range[index][0]));
    return birth_place;
}

//合并区间的函数
function merge(intervals) {
    intervals.sort(function(a, b) {
        if (a[0] !== b[0])
            return a[0] - b[0];
        return a[1] - b[1];
    });
    var len = intervals.length,
        ans = [],
        start, end;

    for (var i = 0; i < len; i++) {
        var s = intervals[i][0],
            e = intervals[i][1];
        if (start === undefined)
            start = s, end = e;
        else if (s <= end)
            end = Math.max(e, end);
        else {
            var part = [start, end];
            ans.push(part);
            start = s;
            end = e;
        }
    }

    if (start !== undefined) {
        var part = [start, end];
        ans.push(part);
    }

    return ans;
}